package com.example.vehiclefabric.controller;

import com.example.vehiclefabric.DTO.AccountDTO;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.StringUtils;
import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.GatewayException;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

import static cn.hutool.extra.spring.SpringUtil.getBean;

/**
 * @name: ContractController
 * @description: 定义默认智能合约的交互方法。
 * @author: Lulu Zhao
 **/
@RestController
@RequestMapping("/account")
@Slf4j
@AllArgsConstructor
public class ContractController {

    final Contract contract = getBean("simpleContract", Contract.class);

    /**
     * @name: queryAccountByKey
     * @description: 查询账户。
     * @params: [key]
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @author: Lulu Zhao
     */
    @GetMapping("/{key}")
    public Map<String, Object> queryAccountByKey(@PathVariable String key) throws GatewayException {

        Map<String, Object> result = Maps.newConcurrentMap();

        byte[] account = contract.evaluateTransaction("query", key);

        result.put("payload", StringUtils.newStringUtf8(account));

        System.out.println(StringUtils.newStringUtf8(account));

        result.put("status", "ok");

        return result;
    }

    /**
     * @name: transferMoney
     * @description: 发起交易。
     * @params: [account]
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @author: Lulu Zhao
     */
    @PutMapping("/transfer")
    public Map<String, Object> transferMoney(@RequestBody AccountDTO account) throws Exception {

        Map<String, Object> result = Maps.newConcurrentMap();

        contract.newProposal("invoke")
                .addArguments(String.valueOf(account.getSender()), String.valueOf(account.getReceiver()), String.valueOf(account.getValue()))
                .build()
                .endorse()
                .submitAsync();

        result.put("status", "ok");

        return result;
    }
}
